#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <errno.h>
#include <cstring>

#define SOCKET_PATH "/tmp/uds_demo_socket"
#define BUFFER_SIZE 256

int main() {
    int sock;
    struct sockaddr_un server_addr;
    char buffer[BUFFER_SIZE];
    int n;

    // 创建 UNIX 域套接字
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("client: socket");
        exit(EXIT_FAILURE);
    }

    // 设置非阻塞模式
    int flags = fcntl(sock, F_GETFL, 0);
    if (flags == -1) {
        perror("client: fcntl F_GETFL");
        close(sock);
        exit(EXIT_FAILURE);
    }

    if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
        perror("client: fcntl F_SETFL");
        close(sock);
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1);

    // 连接到服务器
    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_un)) == -1) {
        perror("client: connect");
        close(sock);
        exit(EXIT_FAILURE);
    }

    std::cout << "client: connected to server" << std::endl;

    // 尝试发送大量数据，模拟缓冲区满
    for (int i = 0; i < 100; ++i) {
        std::cout << "client: sending message " << i << "..." << std::endl;
        n = send(sock, "Hello", 5, 0);

        if (n == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                std::cout << "client: send would block, buffer is full, retrying..." << std::endl;
            } else {
                perror("client: send failed");
                break;
            }
        } else {
            std::cout << "client: message sent " << i << std::endl;
        }

        // Add a small delay to simulate the server's slower processing
        usleep(100000);  // Sleep for 100 ms
    }

    close(sock);
    return 0;
}
